#ifndef _UICONTROL_H
#define _UICONTROL_H

#include <GL/glew.h>

#include "StringUtils.h"
#include "Logger.h"
#include "Vector2.h"
#include "Vector3.h"
#include "GameInfo.h"
#include "Shader.h"
#include "Matrix4.h"
#include "Quaternion.h"
#include "Colour.h"
#include "Input.h"
#include "Delegate.h"

#ifdef GALLIUMENGINE_DLL 
#define GALLIUMENGINE_API __declspec( dllexport )
#else
#define GALLIUMENGINE_API __declspec( dllimport )
#endif

namespace GalliumEngine
{

	class Scene;

	class UIControl
	{
	private:
		std::string id;

		Scene* scene;
		UIControl* parent;

		Shader* shader;

		Quaternion rotationZ;
		Vector2 position;
		Vector2 size;
		float rotZ;
		float depth;
		Colour colour;

		bool visible;

		Matrix4 controlLocal;
		Matrix4 controlWorld;
		Matrix3 scale;

		GLuint vertexArrayID;
		GLuint vertexbuffer;
		GLuint uvbuffer;

		std::vector<Vector3> vertices;
		std::vector<Vector2> uvs;
		std::vector<BindParams> params;

		std::string vertexShader;
		std::string fragmentShader;
	public:
		GALLIUMENGINE_API UIControl(void);
		GALLIUMENGINE_API UIControl::UIControl(std::string _id);
		GALLIUMENGINE_API ~UIControl(void);
		GALLIUMENGINE_API std::string getId();

		GALLIUMENGINE_API void addVertex(Vector3 _vertex);
		GALLIUMENGINE_API void addUv(Vector2 _uv);

		GALLIUMENGINE_API void setControlLocal(Matrix4 _local);
		GALLIUMENGINE_API void setControlWorld(Matrix4 _local);

		GALLIUMENGINE_API Scene* getScene();

		GALLIUMENGINE_API Matrix4 getControlLocal();
		GALLIUMENGINE_API Matrix4 getControlWorld();

		GALLIUMENGINE_API void setSize(Vector2 _size);
		GALLIUMENGINE_API Vector2 getSize();

		GALLIUMENGINE_API void setPosition(Vector2 _position);
		GALLIUMENGINE_API Vector2 getPosition();

		GALLIUMENGINE_API void setDepth(int depth);
		GALLIUMENGINE_API float getDepth();

		GALLIUMENGINE_API void setParent(UIControl *object);
		GALLIUMENGINE_API void setScene(Scene *_scene);

		GALLIUMENGINE_API void setShader(Shader* _shader);
		GALLIUMENGINE_API Shader* getShader();

		GALLIUMENGINE_API void setColour(Colour _colour);
		GALLIUMENGINE_API Colour getColour();

		GALLIUMENGINE_API void setVertexShader(std::string _vertexShader);
		GALLIUMENGINE_API void setFragmentShader(std::string _fragmentShader);

		GALLIUMENGINE_API void addShaderParam(BindParams param);

		GALLIUMENGINE_API GLuint getVertexbuffer();
		GALLIUMENGINE_API GLuint getUvbuffer();

		GALLIUMENGINE_API Matrix3 getScale();
		GALLIUMENGINE_API void setScale(Matrix3 _scale);

		GALLIUMENGINE_API Quaternion getRotationZ();
		GALLIUMENGINE_API void setRotationZ(Quaternion _q);

		GALLIUMENGINE_API std::vector<Vector3> getVertices();
		GALLIUMENGINE_API std::vector<Vector2> getUvs();

		std::vector<BindParams> getShaderParams();

		GALLIUMENGINE_API void setVisible(bool _visible);
		GALLIUMENGINE_API bool getVisible();

		GALLIUMENGINE_API virtual void bind();
		GALLIUMENGINE_API virtual void initialize();
		GALLIUMENGINE_API virtual void deinitialize();

		GALLIUMENGINE_API virtual void update(float delta);
		GALLIUMENGINE_API virtual void draw();
	};

}

#endif

